if(TreeUtil == undefined){
	var TreeUtil = {};
}

TreeUtil.xbDetectBrowser = function()
{
  var oldOnError = window.onerror;
  var element = null;

  window.onerror = null;
  
  // work around bug in xpcdom Mozilla 0.9.1
  window.saveNavigator = window.navigator;

  navigator.OS    = '';
  navigator.version  = parseFloat(navigator.appVersion);
  navigator.org    = '';
  navigator.family  = '';

  var platform;
  if (typeof(window.navigator.platform) != 'undefined')
  {
    platform = window.navigator.platform.toLowerCase();
    if (platform.indexOf('win') != -1)
      navigator.OS = 'win';
    else if (platform.indexOf('mac') != -1)
      navigator.OS = 'mac';
    else if (platform.indexOf('unix') != -1 || platform.indexOf('linux') != -1 || platform.indexOf('sun') != -1)
      navigator.OS = 'nix';
  }

  var i = 0;
  var ua = window.navigator.userAgent.toLowerCase();
  
  if (ua.indexOf('safari') != -1)
  {
    i = ua.indexOf('safari');
    navigator.family = 'safari';
    navigator.org = 'safari';
    navigator.version = parseFloat('0' + ua.substr(i+7), 10);
  }
  else if (ua.indexOf('opera') != -1)
  {
    i = ua.indexOf('opera');
    navigator.family  = 'opera';
    navigator.org    = 'opera';
    navigator.version  = parseFloat('0' + ua.substr(i+6), 10);
  }
  else if ((i = ua.indexOf('msie')) != -1)
  {
    navigator.org    = 'microsoft';
    navigator.version  = parseFloat('0' + ua.substr(i+5), 10);
    
    if (navigator.version < 4)
      navigator.family = 'ie3';
    else
      navigator.family = 'ie4'
  }
  else if (ua.indexOf('gecko') != -1)
  {
    navigator.family = 'gecko';
    var rvStart = ua.indexOf('rv:');
    var rvEnd   = ua.indexOf(')', rvStart);
    var rv      = ua.substring(rvStart+3, rvEnd);
    var rvParts = rv.split('.');
    var rvValue = 0;
    var exp     = 1;

    for (var i = 0; i < rvParts.length; i++)
    {
      var val = parseInt(rvParts[i]);
      rvValue += val / exp;
      exp *= 100;
    }
    navigator.version = rvValue;

    if (ua.indexOf('netscape') != -1)
      navigator.org = 'netscape';
    else if (ua.indexOf('compuserve') != -1)
      navigator.org = 'compuserve';
    else
      navigator.org = 'mozilla';
  }
  else if ((ua.indexOf('mozilla') !=-1) && (ua.indexOf('spoofer')==-1) && (ua.indexOf('compatible') == -1) && (ua.indexOf('opera')==-1)&& (ua.indexOf('webtv')==-1) && (ua.indexOf('hotjava')==-1))
  {
    var is_major = parseFloat(navigator.appVersion);
    
    if (is_major < 4)
      navigator.version = is_major;
    else
    {
      i = ua.lastIndexOf('/')
      navigator.version = parseFloat('0' + ua.substr(i+1), 10);
    }
    navigator.org = 'netscape';
    navigator.family = 'nn' + parseInt(navigator.appVersion);
  }
  else if ((i = ua.indexOf('aol')) != -1 )
  {
    // aol
    navigator.family  = 'aol';
    navigator.org    = 'aol';
    navigator.version  = parseFloat('0' + ua.substr(i+4), 10);
  }
  else if ((i = ua.indexOf('hotjava')) != -1 )
  {
    // hotjava
    navigator.family  = 'hotjava';
    navigator.org    = 'sun';
    navigator.version  = parseFloat(navigator.appVersion);
  }

  window.onerror = oldOnError;
}

TreeUtil.xbDetectBrowser();



 
// Definition of class Folder 
// ***************************************************************** 
TreeUtil.Folder = function(folderDescription, hreference, name, data) //constructor 
{ 
  this.type = "folder";
  //constant data 
  this.data = data;
  /**
   * 子节点数据是否已经取过来了（用于ajax树）
   */
  this.isChildrenDataInitialized = false;
  /**
   * 子节点数据是否正在获取中取过来了（用于ajax树）
   */
  this.isInitializingChildren = false;
  /**
   * 初始化数据回调函数队列
   */
  this.afterInitializeCBQueue = [];
  /**
   * checkbox 是否被人为点击过
   */
  this.checkboxChanged = false;
  /**
   * 是否正在拖动
   */
  this.isDragging = false;
  this.name = name;
  this.desc = folderDescription; 
  this.hreference = hreference;
  this.id = -1;
  this.navObj = 0;
  this.iconImg = 0; 
  this.nodeImg = 0;
  this.iconSrc = TreeUtil.ICONPATH + "ftv2folderopen.gif";
  this.iconSrcClosed = TreeUtil.ICONPATH + "ftv2folderclosed.gif";
  this.children = new Array;
  this.nChildren = 0;
  this.level = 0;
  this.leftSideCoded = "";
  this.isLastNode=false;
  this.parentObj = null;
  this.maySelect=true;
  this.prependHTML = "";
 
  //dynamic data 
  this.isOpen = false;
  this.isLastOpenedFolder = false;
  this.isRendered = false;
 
  //methods 
  this.initialize = TreeUtil.initialize ;
  this.setState = TreeUtil.setState ;
  this.addChild = TreeUtil.addChild ;
  this.addChildren = TreeUtil.addChildren;
  this.createIndex = TreeUtil.createIndex ;
  this.escondeBlock = TreeUtil.escondeBlock;
  this.esconde = TreeUtil.escondeFolder ;
  this.folderMstr = TreeUtil.folderMstr ;
  this.renderOb = TreeUtil.drawFolder ;
  this.totalHeight = TreeUtil.totalHeight ;
  this.subEntries = TreeUtil.subEntries ;
  this.linkHTML = TreeUtil.linkHTML;
  this.blockStartHTML = TreeUtil.blockStartHTML;
  this.blockEndHTML = TreeUtil.blockEndHTML;
  this.nodeImageSrc = TreeUtil.nodeImageSrc;
  this.iconImageSrc = TreeUtil.iconImageSrc;
  this.getID = TreeUtil.getID;
  this.forceOpeningOfAncestorFolders = TreeUtil.forceOpeningOfAncestorFolders;
} 
 
TreeUtil.initialize = function(level, lastNode, leftSide) 
{ 
  var i=0, nc = this.nChildren; 
   
  this.createIndex() ;
  this.level = level;
  this.leftSideCoded = leftSide;

  if (TreeUtil.browserVersion == 0 || TreeUtil.STARTALLOPEN==1)
    this.isOpen=true;

  if (level>0)
    if (lastNode) //the last child in the children array 
		leftSide = leftSide + "0";
	else
		leftSide = leftSide + "1";

  this.isLastNode = lastNode;
 
  if (nc > 0) 
  { 
    level = level + 1 ;
    for (i=0 ; i < this.nChildren; i++)  
    {
      if (typeof this.children[i].initialize == 'undefined') //document node was specified using the addChildren function
      {
        if (typeof this.children[i][0] == 'undefined' || typeof this.children[i] == 'string')
        {
          this.children[i] = ["item incorrectly defined", ""];
        }

        //Basic initialization of the Item object
        //These members or methods are needed even before the Item is rendered
        this.children[i].initialize=initializeItem;
        this.children[i].createIndex=TreeUtil.createIndex;
        if (typeof this.children[i].maySelect == 'undefined')
          this.children[i].maySelect=true;
        this.children[i].forceOpeningOfAncestorFolders = TreeUtil.forceOpeningOfAncestorFolders;
      }
      if (i == this.nChildren-1) 
        this.children[i].initialize(level, 1, leftSide);
      else 
        this.children[i].initialize(level, 0, leftSide);
    } 
  } 
} 

TreeUtil.drawFolder = function(insertAtObj) 
{ 
	//maybe insertAtObj is deleted
	if(insertAtObj != undefined && insertAtObj.parentNode == undefined){
		return;
	}
  var nodeName = "";
  var auxEv = "";
  var docW = "";
  var i=0;

  TreeUtil.finalizeCreationOfChildDocs(this);

  this.leftSideCoded = TreeUtil.getLeftSideCoded(this);
  var leftSide = TreeUtil.leftSideHTML(this.leftSideCoded, this.level);

  if (TreeUtil.browserVersion > 0) 
    auxEv = "<a ondblclick='TreeUtil.dblclickOnNode(\"" + this.getID() + "\")' onclick='TreeUtil.clickOnNode(\"" + this.getID() + "\")' href='javascript:undefined'>" ;
  else 
    auxEv = "<a>" ;

  nodeName = this.nodeImageSrc();
 
  if (this.level>0){ 
    if (this.isLastNode) //the last child in the children array ;
	    leftSide = leftSide + "<td valign=middle width='16' style='height:22px;'>" + auxEv + "<img name='nodeIcon" + this.id + "' id='nodeIcon" + this.id + "' src='" + nodeName + "' width=16 height=22 border=0></a></td>";
    else 
      	leftSide = leftSide + "<td valign=middle width='16' style='height:22px;background:url(" + TreeUtil.ICONPATH + "ftv2vertline.gif)'>" + auxEv + "<img name='nodeIcon" + this.id + "' id='nodeIcon" + this.id + "' src='" + nodeName + "' width=16 height=22 border=0></a></td>";
  }else{
	leftSide = leftSide + "<td style='width:16px;height:22px;'><img onclick='TreeUtil.clickOnNode(\"" + this.getID() + "\")' onclick='TreeUtil.clickOnNode(\"" + this.getID() + "\")' id='nodeIcon" + this.id + "' style='cursor:pointer;margin:0px 0px 0px 5px;width:9px;height:9px;' src='" + TreeUtil.ICONPATH + "treeUnexpandFolder.gif'/></td>";		
  }
  this.isRendered = true;

  if (TreeUtil.browserVersion == 2) { 
    if (!TreeUtil.doc.yPos) 
      TreeUtil.doc.yPos=20 ;
  } 

  docW = this.blockStartHTML("folder");

  docW = docW + "<tr>" + leftSide + "<td valign=middle style='height:22px;'><div class='treeDragDiv' id='drag" + this.id + "'>";
  if (this.data.options.isShowIcon)
  {
    docW = docW + "<div style='float:left'>" + this.linkHTML(false) ;
    docW = docW + "<img id='folderIcon" + this.id + "' name='folderIcon" + this.id + "' src='" + this.iconImageSrc() + "' border=0></a></div>";
  }
  else
  {
	  //if (this.prependHTML == "")
        //docW = docW + "<img src=" + TreeUtil.ICONPATH + "ftv2blank.gif height=2 width=2>";
  }
  if(this.data.options.isShowCheckbox){
  	docW += '<div style="float:left;"><input type=checkbox id="checkbox'+ this.id + '" name="' + this.name + '" value="' + this.data.key + '"/><img id="checkboxDisabledImg' + this.id + '"src="' + TreeUtil.ICONPATH + '/checkboxDisabled.gif" class="treeCheckboxDisabledImg" style="display:none;" onclick="TreeUtil.onCheckboxDisabledImgClick(this);"/></div>';
  }
  if (TreeUtil.WRAPTEXT)
	  docW = docW + this.prependHTML;
  else
	  docW = docW + this.prependHTML;
  if (TreeUtil.USETEXTLINKS) 
  { 
    docW = docW + this.linkHTML(true) ;
    docW = docW + "<span id='desc" + this.id + "'><div id='descContent" + this.id + "' style='float:left;line-height:20px;'>" + this.desc + "</div></span></a>";
  } 
  else 
    docW = docW + this.desc;
  docW = docW + "</div></td>";

  docW = docW + this.blockEndHTML();

  if (insertAtObj == null)
  {
	  if (TreeUtil.supportsDeferral) {
		  //TreeUtil.doc.write("<div id=domRoot></div>"); //transition between regular flow HTML, and node-insert DOM DHTML
		  var name = this.data.options.name;
		  insertAtObj = TreeUtil.getElById(name + "domRoot");
		  insertAtObj.innerHTML += docW;
	  }
	  else
		  TreeUtil.doc.write(docW);
  }
  else
  {
      insertAtObj.insertAdjacentHTML("afterEnd", docW);
  }
  var descId = "desc" + this.id;
  
  //根节点不能修改
  if(this.parentObj){
  	if(this.data.options.isShowToolbar){
	  	this.toolbar = new Best.TreeToolBar(
								{	
									data: this.data,
									path: TreeUtil.ICONPATH,
									elementId:descId,
									isShowAddButton: this.data.options.createActionUrl != "null", //是否显示添加按钮
									isShowEditButton: this.data.options.deleteActionUrl != "null", //是否显示编辑按钮
									isShowDeleteButton: this.data.options.changeParentActionUrl != "null", //是否显示删除按钮
									afterAdd: function(){
												  TreeUtil.createNewItem(this);
											  }.bind(this),
									afterEdit: function(){
											       TreeUtil.startEdit(this);
											   }.bind(this),
									afterDelete: function(){
											       TreeUtil.deleteObj(this);
											   }.bind(this)									   
									
								});
  	}	 
  }
  var id = "drag"+this.id;
  //根节点不能拖动
  if(this.data.options.changeParentActionUrl != "null"){
	  if(this.parentObj){
	  	  Position.includeScrollOffsets = true;
		  this.draggable = new Draggable(id, 
		  						{
		  							revert:true,
		  							ghosting:true,
		  							onBeforeStart: function(){
		  								if(this.toolbar){
  										 	this.toolbar.hide();
  										 }
		  							},
		  							onStart: function(element){
		  										 this.isDragging = true;
		  										 if(this.toolbar){
		  										 	this.toolbar.hide();
		  										 }
		  									 }.bind(this),
		  							onEnd: function(element){
		  										 setTimeout( 
		  										 			function(){
											 					this.isDragging = false;
											 				}.bind(this),
											 				100);
		  									 }.bind(this),
		  							delay: 100,
		  							scroll: this.data.options.scrollContainerId
		  						});
		 						
	  }
	  Droppables.add(id,
	  		{
	  			hoverclass:'dragOver',
	  			onDrop:
	  				function(element, dropon, event){
	  					TreeUtil.changeParentFolder(element, dropon);
	  				}
	  		});
  }
  if (TreeUtil.browserVersion != 0)
  { 
    this.navObj = TreeUtil.getElById("folder"+this.id);
    if (this.data.options.isShowIcon)
      this.iconImg = TreeUtil.getElById("folderIcon"+this.id) ;
    this.nodeImg = TreeUtil.getElById("nodeIcon"+this.id);
    if (this.data.options.isShowCheckbox){
   	  this.checkbox = TreeUtil.getElById("checkbox"+this.id);
   	  this.checkboxDisabledImg = TreeUtil.getElById("checkboxDisabledImg"+this.id);
   	  
   	  if(this.checkbox != undefined){
	   	  this.checkbox.onclick = TreeUtil.oncheckboxClick.bind(this, this);
   	  }
   	  if(this.checkboxDisabledImg != undefined){
	   	  this.checkboxDisabledImg.onclick = TreeUtil.onCheckboxDisabledImgClick.bind(this, this);
   	  }
   	  
  	  if(this.checkbox != null && !this.checkboxChanged){
	   	  if(this.data.checkboxState == 1 || this.data.checkboxState == 3){
	   	  	this.checkbox.checked = true;
	      }else{
	      	this.checkbox.checked = false;
	      }
	      if(this.data.checkboxState == 3){
	   	  	this.checkbox.disabled = true;
	   	  	TreeUtil.onCheckboxDisabled(this);
	   	  }
	   	  if(this.data.checkboxState == 1){
	   	  	TreeUtil.oncheckboxClick(this);
	   	  }
  	  }
  	  if(!this.data.canBeChecked){
      	  this.checkbox.style.display = 'none';
      }
   	  if(this.parentObj == undefined ){
   	  }else{
   	  	  var checkedNodeKeys = this.data.options.checkedNodeKeys;
   	  	  var index = checkedNodeKeys.indexOf(this.data.key);
   	  	  if(index == -1){
   	  	  	  index = checkedNodeKeys.indexOf("^_^" + this.data.key);
   	  	  }
   	  	  if(index != -1){
   	  	  	  checkedNodeKeys.splice(index, 1);
   	  	  }
   	  }
   	  
    }
  } 
  var renderDecorator = this.data.options.renderDecorator;
  if(renderDecorator != undefined){
	renderDecorator(this);
  }
}
/**
 * checkbox 灰掉替代图片的onclick处理函数
 */
TreeUtil.onCheckboxDisabledImgClick = function(obj){
	var img = TreeUtil.getElById("checkboxDisabledImg" + obj.id);
	img.style.display = "none";
	var checkbox = img.previousSibling;
	checkbox.style.display = "";
	checkbox.disabled = false;
	checkbox.checked = false;
	TreeUtil.oncheckboxClick(obj);
}
/**
 * 当一个checkbox被disabled时调用
 */
TreeUtil.onCheckboxDisabled = function(obj){
	var checkbox = obj.checkbox;
	var img = checkbox.nextSibling;
	if(img != undefined && img.tagName == "IMG"){
		checkbox.style.display = "none";
		if(obj.data.canBeChecked){
			img.style.display = "";
		}
	}
}

/**
 * 当一个checkbox被enabled时调用
 */
TreeUtil.onCheckboxEnabled = function(obj){
	var checkbox = obj.checkbox;
	var img = checkbox.nextSibling;
	if(img != undefined && img.tagName == "IMG"){
		if(obj.data.canBeChecked){
			checkbox.style.display = "";
		}
		checkbox.disabled = false;
		img.style.display = "none";
	}
}
TreeUtil.setState = function(isOpen, isRealClick) 
{ 
  if(isRealClick == undefined){
  	isRealClick = true;
  }
  var subEntries ;
  var totalHeight ;
  var fIt = 0 ;
  var i=0 ;
  var currentOpen;
 
  if (isOpen == this.isOpen) 
    return 
 
  this.isOpen = isOpen;

  if (!this.isOpen && this.isLastOpenedfolder)
  {
		TreeUtil.lastOpenedFolder = null;
		this.isLastOpenedfolder = false;
  }
  TreeUtil.propagateChangesInState(this, isRealClick) ;
}

/**
 * 删除所有子孙节点的div
 */
TreeUtil.removeAllChildNavObj = function(folderObj){
	var child;
	for(var i=0; i<folderObj.nChildren; i++){
		child = folderObj.children[i];
		if(child.type == "folder"){
			TreeUtil.removeAllChildNavObj(child);
		}
		if(child.navObj != null && child.navObj.parentNode != null){
			child.navObj.parentNode.removeChild(child.navObj);
		}
		child.isRendered = false;
	}
}
TreeUtil.propagateChangesInState = function(folder, isRealClick) 
{   
  if(isRealClick == undefined){
  	isRealClick = true;
  }
  if(isRealClick && folder.data.isStatic){
  	 	folder.data.isStatic = false;
		TreeUtil.removeAllChildNavObj(folder);
		TreeUtil.initializeChildrenData(folder, TreeUtil.propagateChangesInState.bind(this, folder, isRealClick));
		return;
  }else{
	  if(!folder.isChildrenDataInitialized){
	  	TreeUtil.initializeChildrenData(folder, TreeUtil.propagateChangesInState.bind(this, folder, isRealClick));
	  	return;
	  }
  }
  //Change icon
  if(!folder.data.isLeaf && folder.level == 0){
  	if(folder.isOpen){
  		folder.nodeImg.src = TreeUtil.ICONPATH + "treeExpandFolder.gif";
  	}else{
  		folder.nodeImg.src = TreeUtil.ICONPATH + "treeUnexpandFolder.gif";
  	}
  }
  if (!folder.data.isLeaf && folder.level>0)  //otherwise the one given at render stays
    folder.nodeImg.src = folder.nodeImageSrc();

  //Change node
  if (folder.data.options.isShowIcon)
    folder.iconImg.src = folder.iconImageSrc();

  //Propagate changes
  for (var i=folder.nChildren-1; i>=0; i--) {
    if (folder.isOpen) 
      folder.children[i].folderMstr(folder.navObj);
    else 
  	  folder.children[i].esconde() ;
  }
  if(folder.data.options.isShowCheckbox){
  	if(folder.data.checkboxState == 1 || folder.checkboxChanged){
		TreeUtil.oncheckboxClick(folder);
  	}
  }
}
/**
 * 初始化folder的子节点数据
 * @param folder
 * 			要取子数据的节点
 * @param afterInitializeChildrenDataCB
 * 			初始化的回调函数
 * @return
 * 			如果正在初始化则返回false，否则返回true
 * 			
 */
TreeUtil.initializeChildrenData = function(folder, afterInitializeChildrenData){
	var url = folder.data.options.getChildrenDataUrl;
	folder.afterInitializeCBQueue.push(afterInitializeChildrenData);
	if(folder.isInitializingChildren == false){
		folder.isInitializingChildren = true;
	}else{
		return false;
	}
	jQuery.getJSON
		(
			url,
			{key: folder.data.key},
			function(dataFromServer){
				if(dataFromServer[0] == "success"){
					try{
						var children = dataFromServer[4].children;
						folder.nChildren = 0;
						folder.children = [];
						var treeInstance = null;
						for(var i=0; i<children.length; i++){
							var node = children[i];
							node.options = folder.data.options;
							if(node.options.checkedNodeKeys.indexOf(node.key) != -1){
								node.checkboxState = 1;
							}else if(node.options.checkedNodeKeys.indexOf("^_^" + node.key) != -1){
								node.checkboxState = 3;
							}
							var name = folder.name;
							if(node.isLeaf){
								if(treeInstance == null){
									treeInstance = eval(name);
								}
								var linkUrl = TreeUtil.getLinkUrl(node, "javascript:undefined");
								var link = TreeUtil.gLnk(treeInstance.options.target, node.value, linkUrl, name, node);
								TreeUtil.insDoc(folder, link);
							}else{
								var childFolder = TreeUtil.gFld(node.value, "javascript:undefined", name, node);
								TreeUtil.insFld(folder, childFolder);
							}
						}
						folder.isChildrenDataInitialized = true;
						var foldersTree = folder.data.options.treeInstance.foldersTree;
						foldersTree.initialize(0, true, "") ;
					}catch(e){
						
					}					
				}else{
					Utils.showAjaxTip(dataFromServer);
				}
				folder.isInitializingChildren = false;
				for(var i=0; i<folder.afterInitializeCBQueue.length; i++){
					folder.afterInitializeCBQueue[i]();
				}
				folder.afterInitializeCBQueue = [];
			}
		);
	return true;
}
TreeUtil.escondeFolder = function() 
{ 
  this.escondeBlock();
   
  this.setState(0) ;
} 
 
TreeUtil.linkHTML = function(isTextLink) 
{ 
  var docW = "";

  if (this.hreference) 
  { 
	if (TreeUtil.USEFRAMES)
	  docW = docW + "<a href='" + this.hreference + "' TARGET=\"basefrm\" ";
	else
	  docW = docW + "<a href='" + this.hreference + "' TARGET=_top ";
        
    if (isTextLink) {
        docW += "id=\"itemTextLink"+this.id+"\" ";
    }

    if (TreeUtil.browserVersion > 0) 
      docW = docW + " ondblClick='javascript:TreeUtil.dblclickOnFolder(\""+this.getID()+"\")' onClick='javascript:TreeUtil.clickOnFolder(\""+this.getID()+"\")'";

    docW = docW + ">";
  } 
  else 
    docW = docW + "<a>" ;

  return docW;
}
/**
 * 添加子节点
 * @param childNode
 * @param mode
 * 			模式：
 * 				1: 在尾部追加
 * 				2: 在头部插入
 */
TreeUtil.addChild = function(childNode, mode) 
{ 
  if(mode == undefined){
  	mode = 1;
  }
  if(mode == 1){
  	this.children[this.nChildren] = childNode ;
  }else{
  	this.children.splice(0, 0, childNode);
  }
  childNode.parentObj = this;
  this.nChildren++ ;
  return childNode ;
} 

//The list can contain either a Folder object or a sub list with the arguments for Item 
TreeUtil.addChildren = function(listOfChildren) 
{ 
  this.children = listOfChildren ;
  this.nChildren = listOfChildren.length;
  for (i=0; i<this.nChildren; i++)
    this.children[i].parentObj = this;
} 

TreeUtil.subEntries = function() 
{ 
  var i = 0 ;
  var se = this.nChildren ;
 
  for (i=0; i < this.nChildren; i++){ 
    if (this.children[i].children) //is a folder 
      se = se + this.children[i].subEntries() ;
  } 
 
  return se ;
} 

TreeUtil.nodeImageSrc = function() {
  var srcStr = "";

  if (this.isLastNode) //the last child in the children array 
  { 
    if (this.data.isLeaf)
      srcStr = TreeUtil.ICONPATH + "ftv2lastnode.gif";
    else
      if (this.isOpen)
        srcStr = TreeUtil.ICONPATH + "ftv2mlastnode.gif"  ;
      else
        srcStr = TreeUtil.ICONPATH + "ftv2plastnode.gif"  ;
  } 
  else 
  { 
    if (this.data.isLeaf)
      srcStr = TreeUtil.ICONPATH + "ftv2node.gif";
    else
      if (this.isOpen)
        srcStr = TreeUtil.ICONPATH + "ftv2mnode.gif";
      else
        srcStr = TreeUtil.ICONPATH + "ftv2pnode.gif";
  }   
  return srcStr;
}

TreeUtil.iconImageSrc = function() {
  if (this.isOpen)
    return(this.iconSrc);
  else
    return(this.iconSrcClosed);
} 
 
// Definition of class Item (a document or link inside a Folder) 
// ************************************************************* 
 
TreeUtil.Item = function(itemDescription, name, data) // Constructor 
{ 
  this.type = "item";
  // constant data 
  this.name = name;
  this.data = data;
  this.desc = itemDescription ;
  /**
   * 是否正在拖动
   */
  this.isDragging = false;
  this.level = 0;
  this.isLastNode = false;
  this.leftSideCoded = "";
  this.parentObj = null;

  this.maySelect=true;

  this.initialize = TreeUtil.initializeItem;
  this.createIndex = TreeUtil.createIndex;
  this.forceOpeningOfAncestorFolders = TreeUtil.forceOpeningOfAncestorFolders;

  TreeUtil.finalizeCreationOfItem(this);
} 

//Assignments that can be delayed when the item is created with folder.addChildren
//The assignments that cannot be delayed are done in addChildren and in initialize
//Additionaly, some assignments are also done in finalizeCreationOfChildDocs itself
TreeUtil.finalizeCreationOfItem = function(itemArray)
{
  itemArray.navObj = 0; //initialized in render() 
  itemArray.iconImg = 0; //initialized in render() 
  itemArray.iconSrc = TreeUtil.ICONPATH + "ftv2doc.gif" ;
  itemArray.isRendered = false;
  itemArray.nChildren = 0;
  itemArray.prependHTML = "";
 
  // methods 
  itemArray.escondeBlock = TreeUtil.escondeBlock;
  itemArray.esconde = TreeUtil.escondeBlock;
  itemArray.folderMstr = TreeUtil.folderMstr ;
  itemArray.renderOb = TreeUtil.drawItem ;
  itemArray.totalHeight = TreeUtil.totalHeight ;
  itemArray.blockStartHTML = TreeUtil.blockStartHTML;
  itemArray.blockEndHTML = TreeUtil.blockEndHTML;
  itemArray.getID = TreeUtil.getID;
}

TreeUtil.initializeItem = function(level, lastNode, leftSide) 
{  
  this.createIndex() ;
  this.level = level;
  this.leftSideCoded = leftSide;
  this.isLastNode = lastNode;
} 
TreeUtil.getLeftSideCoded = function(obj){
	if(!obj.parentObj ){
		return "";
	}
	if(obj.parentObj.isLastNode){
		if(!obj.parentObj.parentObj){
			return "";
		}
		return obj.parentObj.leftSideCoded + "0";
	}else{
		return obj.parentObj.leftSideCoded + "1";
	}
}
TreeUtil.drawItem = function(insertAtObj) 
{ 
	//maybe insertAtObj is deleted
	if(insertAtObj.parentNode == undefined){
		return;
	}
  this.leftSideCoded = TreeUtil.getLeftSideCoded(this);
  var leftSide = TreeUtil.leftSideHTML(this.leftSideCoded, this.level);
  var docW = "";

  var fullLink = "href=\""+this.link+"\" target=\""+this.target+"\" ondblClick=\"TreeUtil.dblclickOnLink('"+this.getID()+"\', '"+this.link+"','"+this.target+"');return false;\" onClick=\"TreeUtil.clickOnLink('"+this.getID()+"\', '"+this.link+"','"+this.target+"');return false;\"";
  this.isRendered = true;

  if (this.level>0) 
    if (this.isLastNode) //the last 'brother' in the children array 
    { 
      leftSide = leftSide + "<td valign=middle width='16' style='height:22px;'><img src='" + TreeUtil.ICONPATH + "ftv2lastnode.gif' width=16 height=22></td>";
    } 
    else 
    { 
      leftSide = leftSide + "<td valign=middle width='16' style='height:22px;background:url(" + TreeUtil.ICONPATH + "ftv2vertline.gif)'><img src='" + TreeUtil.ICONPATH + "ftv2node.gif' width=16 height=22></td>";
    } 

  docW = docW + this.blockStartHTML("item");

  docW = docW + "<tr>" + leftSide + "<td valign=middle style='height:22px;'><div class='treeDragDiv' id='drag" + this.id +"'>";
  if (this.data.options.isShowIcon)
      docW = docW + "<div style='float:left'><a " + fullLink  + " id=\"itemIconLink"+this.id+"\">" + "<img id='itemIcon"+this.id+"' " + "src='"+this.iconSrc+"' border=0>" + "</a></div>";
  
  if(this.data.options.isShowCheckbox){
  	docW += '<div style="float:left"><input type=checkbox id="checkbox'+ this.id + '" name="' + this.name + '" value="' + this.data.key + '"/><img id="checkboxDisabledImg' + this.id + '"src="' + TreeUtil.ICONPATH + '/checkboxDisabled.gif" class="treeCheckboxDisabledImg" style="display:none;" onclick="TreeUtil.onCheckboxDisabledImgClick(this);"/></div>';;
  }
  if (TreeUtil.WRAPTEXT)
    docW = docW + this.prependHTML;
  else
    docW = docW + this.prependHTML;

  if (TreeUtil.USETEXTLINKS) 
    docW = docW + "<a " + fullLink + " id=\"itemTextLink"+this.id+"\"><span id='desc" + this.id + "'><div id='descContent" + this.id + "' style='float:left;line-height:20px;'>" + this.desc + "</div></span></a>";
  else 
    docW = docW + this.desc;
  docW = docW + "</div></td>";

  docW = docW + this.blockEndHTML();
 
  if (insertAtObj == null)
  {
	  TreeUtil.doc.write(docW);
  }
  else
  {
      insertAtObj.insertAdjacentHTML("afterEnd", docW);
  }
  
  var descId = "desc" + this.id;
  
  //根节点不能修改
  if(this.parentObj){
  	if(this.data.options.isShowToolbar){
	  	this.toolbar = new Best.TreeToolBar(
								{	
									data: this.data,
									path: TreeUtil.ICONPATH,
									elementId:descId,
									isShowAddButton: this.data.options.createActionUrl != "null", //是否显示添加按钮
									isShowEditButton: this.data.options.deleteActionUrl != "null", //是否显示编辑按钮
									isShowDeleteButton: this.data.options.changeParentActionUrl != "null", //是否显示删除按钮
									afterAdd: function(){
												  TreeUtil.createNewItem(this);
											  }.bind(this),
									afterEdit: function(){
											       TreeUtil.startEdit(this);
											   }.bind(this),
									afterDelete: function(){
											       TreeUtil.deleteObj(this);
											   }.bind(this)									   
									
								});	 
  	}
  }
  if(this.data.options.changeParentActionUrl != "null"){
	  var id = "drag"+this.id;
	  this.draggable = new Draggable(id, 
	  						{
	  							revert:true,
	  							ghosting:true,
	  							onBeforeStart: function(){
	  								if(this.toolbar){
									 	this.toolbar.hide();
									 }
	  							},
	  							onStart: function(element){
	  										 this.isDragging = true;
	  										 if(this.toolbar){
	  										 	this.toolbar.hide();
	  										 }
	  									 }.bind(this),
	  							onEnd: function(element){
	  										 setTimeout( 
	  										 			function(){
										 					this.isDragging = false;
										 				}.bind(this),
										 				100);
	  									 }.bind(this),
	  							delay:100,
	  							scroll: this.data.options.scrollContainerId
	  						});
	  Droppables.add(id, 
	  		{
	  			hoverclass:'dragOver',
	  			onDrop:
	  				function(element, dropon, event){
	  					TreeUtil.changeItemParent(element, dropon);
	  				}
	  		});
  }
  if (TreeUtil.browserVersion != 0) { 
    this.navObj = TreeUtil.getElById("item"+this.id)
    if (this.data.options.isShowIcon)
      this.iconImg = TreeUtil.getElById("itemIcon"+this.id)
    if (this.data.options.isShowCheckbox){
   	  this.checkbox = TreeUtil.getElById("checkbox"+this.id);
   	  this.checkboxDisabledImg = TreeUtil.getElById("checkboxDisabledImg"+this.id);
   	  if(this.parentObj == undefined || (this.parentObj != undefined && this.parentObj.checkbox.checked)){
	   	  if(!this.checkboxChanged){
		   	  if(this.data.checkboxState == 1 || this.data.checkboxState == 3){
		   	  	this.checkbox.checked = true;
		      }else{
		      	this.checkbox.checked = false;
		      }
		      if(this.data.checkboxState == 3){
		   	  	this.checkbox.disabled = true;
		   	  	TreeUtil.onCheckboxDisabled(this);
		   	  }
		   	  if(this.data.checkboxState == 1){
		   	  	TreeUtil.oncheckboxClick(this);
		   	  }
	   	  }
   	  }else{
   	  	  var checkedNodeKeys = this.data.options.checkedNodeKeys;
   	  	  var index = checkedNodeKeys.indexOf(this.data.key);
   	  	  if(index == -1){
   	  	  	  index = checkedNodeKeys.indexOf("^_^" + this.data.key);
   	  	  }
   	  	  if(index != -1){
   	  	  	  checkedNodeKeys.splice(index, 1);
   	  	  }
   	  }
      if(this.checkbox != undefined){
       	  this.checkbox.onclick = TreeUtil.oncheckboxClick.bind(this, this);
       	  this.checkboxDisabledImg.onclick = TreeUtil.onCheckboxDisabledImgClick.bind(this, this);
      }
      if(!this.data.canBeChecked){
      	  this.checkbox.style.display = 'none';
      }
    }
  } 
  var renderDecorator = this.data.options.renderDecorator;
  if(renderDecorator != undefined){
	renderDecorator(this);
  }
} 
TreeUtil.oncheckboxClick = function(target, isCallCallBack){
	if(isCallCallBack == undefined){
		isCallCallBack = true;
	}
	if(target.checkbox){
		var checked = target.checkbox.checked;
		if(target.checkbox.disabled){
			TreeUtil.onCheckboxDisabled(target);
		}else{
			TreeUtil.onCheckboxEnabled(target);
		}
		var checkedNodeKeys = target.data.options.checkedNodeKeys;
		if(target.data.options.isRecursive){
			target.checkboxChanged = true;
			
			if(target.checkbox.disabled == false){
				var index = checkedNodeKeys.indexOf(target.data.key);
				if(index == -1){
					index = checkedNodeKeys.indexOf("^_^" + target.data.key);
				}
				if(checked){
					if(index == -1){
						checkedNodeKeys.push(target.data.key);
					}
				}else{
					if(index != -1){
						checkedNodeKeys.splice(index, 1);
					}
				}
				TreeUtil.traverseAllChild
							(
								target, 
								function(obj){
									if(obj.checkbox){
										if(checked){
											TreeUtil.onCheckboxEnabled(obj);
										}else{
											TreeUtil.onCheckboxEnabled(obj);
										}
								   	 	obj.checkbox.checked = checked;
									}
									obj.checkboxChanged = true;
									var index = checkedNodeKeys.indexOf(obj.data.key);
									if(index == -1){
										index = checkedNodeKeys.indexOf("^_^" + obj.data.key);
									}
									if(checked){
										if(index == -1){
											checkedNodeKeys.push(obj.data.key);
										}else{
											index = checkedNodeKeys.indexOf("^_^" + obj.data.key);
											if(index != -1){
												checkedNodeKeys[index] = obj.data.key;
											}
										}
									}else{
										if(index != -1){
											checkedNodeKeys.splice(index, 1);
										}
									}
									return true;
								}
							);
			}
		}
		var parentObj = target.parentObj;
		while(parentObj != null){
			var isAllChildCheckboxChecked = TreeUtil.isAllChildCheckboxChecked(parentObj);
			var index = checkedNodeKeys.indexOf(parentObj.data.key);
			if(isAllChildCheckboxChecked == 1){ //所有子节点都被checked
				if(TreeUtil.hasDisabledChildCheckbox(parentObj)){
					parentObj.checkbox.disabled = true;
					TreeUtil.onCheckboxDisabled(parentObj);
					if(index != -1){
						checkedNodeKeys.splice(index, 1);
					}
				}else{
					if(target.data.options.isRecursive){
						parentObj.checkbox.disabled = false;
						TreeUtil.onCheckboxEnabled(parentObj);
						if(index == -1){
							checkedNodeKeys.push(parentObj.data.key);
						}
					}
				}
				if(target.data.options.isRecursive){
					parentObj.checkbox.checked = true;
				}
			}else if(isAllChildCheckboxChecked == -1){ //所有子节点都没被checked
				if(target.data.options.isRecursive || parentObj.checkbox.disabled){
					parentObj.checkbox.checked = false;
					parentObj.checkbox.disabled = false;
					TreeUtil.onCheckboxEnabled(parentObj);
					if(index != -1){
						checkedNodeKeys.splice(index, 1);
					}
				}
			}else{//部分子节点被checked
				if(target.data.options.isRecursive 
					|| (parentObj.checkbox != null && parentObj.checkbox.disabled) 
					|| (parentObj.checkbox != null && !parentObj.checkbox.checked)){
					if(parentObj.checkbox != null){
						parentObj.checkbox.checked = true;
						parentObj.checkbox.disabled = true;
						TreeUtil.onCheckboxDisabled(parentObj);
					}
					if(index != -1){
						checkedNodeKeys.splice(index, 1);
					}
				}
			}
			parentObj = parentObj.parentObj;
		}
		var oncheckboxclickCB = target.data.options.oncheckboxclick;
		if(oncheckboxclickCB != undefined && isCallCallBack){
			oncheckboxclickCB(target);
		}
	}
}
/**
 * 判断nodeObj的第一级子节点中是否所有checkbox被checked
 * @param nodeObj
 * 			要判断的节点对象
 * @return
 * 			如果所有节点都被checked则返回1,
 * 			如果只有部分节点被checked则返回0,
 * 			如果所有节点都没有被checked则返回-1,
 */
TreeUtil.isAllChildCheckboxChecked = function(nodeObj){
	var result = -1;
	var child;
	var isAllChildCheckboxChecked = true;
	var checkedNum = 0;
	for(var i=0; i<nodeObj.nChildren; i++){
		child = nodeObj.children[i];
		if(child.checkbox && child.checkbox.checked){
			checkedNum++;
		}
	}
	if(checkedNum == 0){
		result = -1;
	}else if(checkedNum == nodeObj.nChildren){
		result = 1;
	}else{
		result = 0;
	}
	if(nodeObj.data.options.treeInstance.isShowingSearchResult){
		if(result == 1){
			result = 0;
		}
	}
	return result;
}
/**
 * 判断nodeObj的第一级子节点中是否有checkbox被disabled
 * @param nodeObj
 * 			要判断的节点对象
 * @return
 * 			是就返回true, 不是返回false
 */
TreeUtil.hasDisabledChildCheckbox = function(nodeObj){
	var result = false;
	var child;
	for(var i=0; i<nodeObj.nChildren; i++){
		child = nodeObj.children[i];
		if(child.checkbox.disabled){
			result = true;
		}
	}
	return result;
}
// Methods common to both objects (pseudo-inheritance) 
// ******************************************************** 
 
TreeUtil.forceOpeningOfAncestorFolders = function() {
  if (this.parentObj == null || this.parentObj.isOpen)
    return
  else {
    this.parentObj.forceOpeningOfAncestorFolders()
    TreeUtil.clickOnNodeObj(this.parentObj, false)
  }
}

TreeUtil.escondeBlock = function() 
{ 
	if(this.navObj){
	  if (TreeUtil.browserVersion == 1 || TreeUtil.browserVersion == 3) { 
	    if (this.navObj.style.display == "none") 
	      return 
	    this.navObj.style.display = "none" 
	  } else { 
	    if (this.navObj.visibility == "hidden") 
	      return 
	    this.navObj.visibility = "hidden" 
	  }
	}     
} 
 
TreeUtil.folderMstr = function(domObj) 
{ 
  if (TreeUtil.browserVersion == 1 || TreeUtil.browserVersion == 3) { 
    if (TreeUtil.t==-1)
      return
    
  }

  if (!this.isRendered)
     this.renderOb(domObj)
  else
    if (TreeUtil.browserVersion == 1 || TreeUtil.browserVersion == 3) 
      this.navObj.style.display = "block" 
    else 
      this.navObj.visibility = "show" 
} 

TreeUtil.blockStartHTML = function(idprefix) {
  var idParam = "id='" + idprefix + this.id + "'"
  var docW = ""

  if (TreeUtil.browserVersion == 2) 
    docW = "<layer "+ idParam + " top=" + TreeUtil.doc.yPos + " visibility=show>"
  else if (TreeUtil.browserVersion != 0)
    docW = "<div " + idParam + " style='display:block;'>"
     
  docW = docW + "<table border=0 cellspacing=0 cellpadding=0 width=100% class='treeTable'>"

  return docW
}

TreeUtil.blockEndHTML = function() {
  var docW = ""

  docW = "</table>"
   
  if (TreeUtil.browserVersion == 2) 
    docW = docW + "</layer>"
  else if (TreeUtil.browserVersion != 0)
    docW = docW + "</div>"

  return docW
}
 
TreeUtil.createIndex = function(){
	var treeInstance = this.data.options.treeInstance; 
 	if(this.id == -1 || this.id == undefined){
  		this.id = treeInstance.options.name + treeInstance.nEntries;
  	} 
  	Best.indexOfEntries[this.id] = this; 
 	treeInstance.nEntries++ ;
} 
 
// total height of subEntries open 
TreeUtil.totalHeight = function() //used with TreeUtil.browserVersion == 2 
{ 
  var h = this.navObj.clip.height 
  var i = 0 
   
  if (this.isOpen) //is a folder and _is_ open 
    for (i=0 ; i < this.nChildren; i++)  
      h = h + this.children[i].totalHeight() 
 
  return h 
} 


TreeUtil.leftSideHTML = function(leftSideCoded, level) {
	var i;
	var retStr = "";
	if(level > 0){
		retStr += "<td style='width:16px;height:22px;'/>";
	}
	for (i=0; i<leftSideCoded.length; i++)
	{
		if (leftSideCoded.charAt(i) == "1")
		{
			retStr = retStr + "<td valign=middle width='16' style='height:22px;background:url(" + TreeUtil.ICONPATH + "ftv2vertline.gif)'><img src='" + TreeUtil.ICONPATH + "ftv2vertline.gif' width=16 height=22></td>"
		}
		if (leftSideCoded.charAt(i) == "0")
		{
			retStr = retStr + "<td valign=middle width='16' style='height:22px;'><img src='" + TreeUtil.ICONPATH + "ftv2blank.gif' width=16 height=22></td>"
		}
	}
	return retStr
}

TreeUtil.getID = function()
{
  //define a .xID in all nodes (folders and items) if you want to PERVESTATE that
  //work when the tree changes. The value eXternal value must be unique for each
  //node and must node change when other nodes are added or removed
  //The value may be numeric or string, but cannot have the same char used in TreeUtil.cookieCutter
  if (typeof this.xID != "undefined") 
    return this.xID
  else
    return this.id
}

 
// Events 
// ********************************************************* 
 
TreeUtil.clickOnFolder = function(folderId, isRealClick) 
{ 
  if(isRealClick == undefined){
  	isRealClick = true;
  }
  var clicked = TreeUtil.findObj(folderId)
  if(clicked.isDragging){
  	clicked.isDragging = false;
  	return;
  }
  if (typeof clicked=='undefined' || clicked==null)
  {
    alert("Unable to find the node object corresponding to ID=" + folderId + ". If the configuration file sets a.xID values, it must set them for ALL nodes, including the foldersTree root.")
    return;
  }

  //if (!clicked.isOpen) {
    TreeUtil.clickOnNodeObj(clicked, isRealClick); 
  //}

  //if (TreeUtil.lastOpenedFolder != null && TreeUtil.lastOpenedFolder != folderId)
  //   TreeUtil.clickOnNode(TreeUtil.lastOpenedFolder); //sets TreeUtil.lastOpenedFolder to null

  if (clicked.nChildren==0) {
    TreeUtil.lastOpenedFolder = folderId;
    clicked.isLastOpenedfolder = true
  }

  if (TreeUtil.isLinked(clicked.hreference)) {
      TreeUtil.highlightObjLink(clicked);
  }
} 
TreeUtil.dblclickOnFolder = function(folderId) 
{ 
  var folderObj = TreeUtil.findObj(folderId)
  if(folderObj.data && folderObj.data.options.onnodedblclick){
  	folderObj.data.options.onnodedblclick(folderObj);
  }
} 
 
TreeUtil.clickOnNode = function(folderId) 
{ 
  fOb = TreeUtil.findObj(folderId);
  if (typeof fOb=='undefined' || fOb==null)
  {
    alert("Unable to find the node object corresponding to ID=" + folderId + ". If the configuration file sets a.xID, it must set foldersTree.xID as well.")
    return;
  }

  TreeUtil.clickOnNodeObj(fOb);
}

TreeUtil.dblclickOnNode = function(folderId) { 
  fOb = TreeUtil.findObj(folderId);
  if(folderObj.data && folderObj.data.options.onnodedblclick){
  	folderObj.data.options.onnodedblclick(folderObj);
  }
}
TreeUtil.clickOnNodeObj = function(folderObj, isRealClick) 
{ 
  if(isRealClick == undefined){
  	isRealClick = true;
  }
  var state = 0; 
  var currentOpen;
  
  TreeUtil.highlightNode(folderObj);
  state = folderObj.isOpen ;
  
  folderObj.setState(!state, isRealClick) //open<->close  

  if(isRealClick){
  	  if(folderObj.data && folderObj.data.options.onnodeclick){
  	  	folderObj.data.options.onnodeclick(folderObj);
  	  }
  }
}

TreeUtil.clickOnLink = function(clickedId, target, windowName) {
	var linkObj = TreeUtil.findObj(clickedId);
	if(linkObj.data && linkObj.data.options.onnodeclick){
  		linkObj.data.options.onnodeclick(linkObj);
  	}
    TreeUtil.highlightObjLink(linkObj);
    if (TreeUtil.isLinked(target)) {
        window.open(target,windowName);
    }
}
TreeUtil.dblclickOnLink = function(clickedId, target, windowName) {
	var linkObj = TreeUtil.findObj(clickedId);
	if(linkObj.data && linkObj.data.options.onnodedblclick){
  		linkObj.data.options.onnodedblclick(linkObj);
  	}
}
// Auxiliary Functions 
// *******************

TreeUtil.finalizeCreationOfChildDocs = function(folderObj) {
  for(i=0; i < folderObj.nChildren; i++)  {
    child = folderObj.children[i]
    if (typeof child[0] != 'undefined')
    {
      // Amazingly, arrays can have members, so   a = ["a", "b"]; a.desc="asdas"   works
      // If a TreeUtil.doc was inserted as an array, we can transform it into an itemObj by adding 
      // the missing members and functions
      child.desc = child[0] 
      TreeUtil.setItemLink(child, TreeUtil.GLOBALTARGET, child[1])   
      TreeUtil.finalizeCreationOfItem(child)
    }
  }
}

TreeUtil.findObj = function(id)
{
	/*
  var i=0;
  var nodeObj;
  
  if (typeof foldersTree.xID != "undefined") {
    nodeObj = TreeUtil.indexOfEntries[i];
    for(i=0;i<TreeUtil.nEntries&&TreeUtil.indexOfEntries[i].xID!=id;i++) //may need optimization
      ;
    id = i
  }*/
	return Best.indexOfEntries[id];
}

TreeUtil.isLinked = function(hrefText) {
    var result = true;
    result = (result && hrefText !=null);
    result = (result && hrefText != '');
    result = (result && hrefText.indexOf('undefined') < 0);
    result = (result && hrefText.indexOf('parent.op') < 0);
    return result;
}

// Do highlighting by changing background and foreg. colors of folder or TreeUtil.doc text
TreeUtil.highlightObjLink = function(nodeObj) {
  if (!TreeUtil.HIGHLIGHT || nodeObj==null || nodeObj.maySelect==false) {//node deleted in DB 
    return;
  }

  if (TreeUtil.browserVersion == 1 || TreeUtil.browserVersion == 3) {
    var clickedDOMObj = TreeUtil.getElById('itemTextLink'+nodeObj.id);
    if (clickedDOMObj != null) {
        TreeUtil.highlightNode(nodeObj);
    }
  }
}
/**
 * 插入folder
 * @param parentFolder
 * 			父节点对象
 * @param childFolder
 * 			子节点对象
 * @param mode
 * 			模式：
 * 				1: 在尾部追加
 * 				2: 在头部插入
 */
TreeUtil.insFld = function(parentFolder, childFolder, mode) 
{ 
  return parentFolder.addChild(childFolder, mode) 
} 
/**
 * 插入folder
 * @param parentFolder
 * 			父节点对象
 * @param document
 * 			子节点对象
 * @param mode
 * 			模式：
 * 				1: 在尾部追加
 * 				2: 在头部插入
 */
TreeUtil.insDoc = function(parentFolder, document, mode) 
{ 
  if(parentFolder){
  	return parentFolder.addChild(document, mode)
  }else{
  	return null;
  } 
} 

TreeUtil.gFld = function(description, hreference, name, data) 
{ 
  folder = new TreeUtil.Folder(description, hreference, name, data);
  return folder;
} 
 
TreeUtil.gLnk = function(target, description, linkData, name, data) 
{ 
  newItem = new TreeUtil.Item(description, name, data);
  TreeUtil.setItemLink(newItem, target, linkData);
  return newItem;
} 

TreeUtil.setItemLink = function(item, target, linkData) {
  var targetFlag = "";
  var target = "";
  var protocolFlag = "";
  var protocol = "";

  item.link = linkData;    
  item.target = target
}

//Function created  for backwards compatibility purposes
//Function contents voided in March 2004
TreeUtil.oldGLnk = function(target, description, linkData)
{
}
 
TreeUtil.preLoadIcons = function() {
       arImageSrc = new Array (
           "ftv2vertline.gif",
           "ftv2mlastnode.gif",
           "ftv2mnode.gif",
           "ftv2plastnode.gif",
           "ftv2pnode.gif",
           "ftv2blank.gif",
           "ftv2lastnode.gif",
           "ftv2node.gif",
           "ftv2folderclosed.gif",
           "ftv2folderopen.gif",
           "ftv2doc.gif"
           )
       arImageList = new Array ();
       for (var i=0; i<arImageSrc.length; i++) {
           arImageList[i] = new Image();
           arImageList[i].src = TreeUtil.ICONPATH + arImageSrc[i];
       }
   }

//Open some folders for initial layout, if necessary
TreeUtil.setInitialLayout = function(foldersTree) {
  if (TreeUtil.browserVersion > 0 && !TreeUtil.STARTALLOPEN){
  	try{
		TreeUtil.clickOnNodeObj(foldersTree, false);  		
  	}catch(e){
  		
  	}
  }
    
  
  if (!TreeUtil.STARTALLOPEN && (TreeUtil.browserVersion > 0) && TreeUtil.PRESERVESTATE)
		TreeUtil.PersistentFolderOpening();
}

//Used with NS4 and TreeUtil.STARTALLOPEN
TreeUtil.renderAllTree = function(nodeObj, parent) {
  if(!nodeObj.isRendered){
  	nodeObj.renderOb(parent);
  	
  	if(!nodeObj.data.isLeaf){
  		nodeObj.isOpen = true;
  	}
  }
  
  if(nodeObj.isChildrenDataInitialized){
  	TreeUtil.renderAllChild(nodeObj);
  }else{
  	if(!nodeObj.data.isLeaf){
  		TreeUtil.initializeChildrenData(nodeObj, TreeUtil.renderAllChild.bind(this, nodeObj));
  	}
  }
  
}
TreeUtil.renderAllChild = function(nodeObj){
	if(!nodeObj.isOpen && !nodeObj.data.isLeaf){
		TreeUtil.clickOnNodeObj(nodeObj, false);
	}
  //log(nodeObj.data.key + "," + nodeObj.isOpen + "," + nodeObj.data.isLeaf + "," + (nodeObj.nChildren>0));
  
  if (TreeUtil.supportsDeferral){
    for (var i=nodeObj.nChildren-1; i>=0; i--) 
      TreeUtil.renderAllTree(nodeObj.children[i], nodeObj.navObj)
  }else{
    for (var i=0 ; i < nodeObj.nChildren; i++) 
      TreeUtil.renderAllTree(nodeObj.children[i], null);
  }
}
TreeUtil.hideWholeTree = function(nodeObj, nodeObjMove) {
  var heightContained=0;
  var childrenMove=nodeObjMove;
  if(nodeObj.isOpen && !nodeObj.data.isLeaf){
  	TreeUtil.clickOnNodeObj(nodeObj, false);
  }
  //log(nodeObj.data.key + "," + nodeObj.isOpen);
  for (var i=0 ; i < nodeObj.nChildren; i++) {
    var heightContainedInChild = TreeUtil.hideWholeTree(nodeObj.children[i], childrenMove)
  }

  return heightContained;
}

/**
 * 遍历nodeObj的所有子节点，并调用func(nodeObj)
 * @param nodeObj
 * 			要遍历的节点
 * @param func
 * 			遍历的处理函数
 * @param isTraverseUninitializedNode
 * 			是否需要遍历尚未初始化的节点（用于ajax树）
 */
TreeUtil.traverseAllChild = function(nodeObj, func, isTraverseUninitializedNode){
	if(isTraverseUninitializedNode == undefined){
		isTraverseUninitializedNode = false;
	}
	if(!nodeObj.isChildrenDataInitialized && isTraverseUninitializedNode){
		if(!nodeObj.data.isLeaf){
			TreeUtil.initializeChildrenData(nodeObj, TreeUtil.traverseAllChild.bind(this, nodeObj, func));
			return;
		}
	}
	if(isTraverseUninitializedNode){
		if(!nodeObj.isRendered){
			nodeObj.renderOb(nodeObj.parentObj.navObj);
		}
	}
	if(func(nodeObj)){
		for (var i=0; i < nodeObj.nChildren; i++) {
			var child = nodeObj.children[i];
		    TreeUtil.traverseAllChild(child, func, isTraverseUninitializedNode);
		}
	}
}
/**
 * 宽度优先遍历
 * @param rootNodeObj
 * 			要遍历的树的根节点
 * @param func
 * 			对每个节点的处理函数(返回true表示需要继续遍历子节点，false表示不需要继续遍历子节点）
 * @param isTraverseUninitializedNode
 * 			是否需要遍历尚未初始化的节点（用于ajax树）
 * @param afterFinished
 * 			遍历完成后的回调函数
 */
TreeUtil.widthFirstTraverse = function(rootNodeObj, isTraverseUninitializedNode, func, afterFinished){
	if(afterFinished == undefined){
		afterFinished = Prototype.emptyFunction;
	}
	var queue = [];
	queue.push(rootNodeObj);
	var child, state = {isGetting: false}, isGetting = false;
	function working(){
		if(!state.isGetting){
			var node = queue.shift();
			
			if(func(node)){
				if(node.isChildrenDataInitialized){
					for (var i=0; i < node.nChildren; i++) {
						queue.push(node.children[i]);
					}
				}else if(isTraverseUninitializedNode){
					
					if(!node.data.isLeaf){
						state.isGetting = true;
						TreeUtil.initializeChildrenData(
								node, 
								function(){
									state.isGetting = false;
									for (var i=node.nChildren-1; i >=0 ; i--) {
										queue.push(node.children[i]);
									}
									
								});
						
					}
				}
			}
		}
		if(state.isGetting){
			setTimeout(working, 2);
		}else{
			if(queue.length > 0){
				working();
			}else{
				afterFinished();
			}
		}
	}
	working();
	
}
// Simulating inserAdjacentHTML on NS6
// Code by thor@jscript.dk
// ******************************************

if(typeof HTMLElement!="undefined" && !HTMLElement.prototype.insertAdjacentElement){
	HTMLElement.prototype.insertAdjacentElement = function (where,parsedNode)
	{
		switch (where){
		case 'beforeBegin':
			this.parentNode.insertBefore(parsedNode,this)
			break;
		case 'afterBegin':
			this.insertBefore(parsedNode,this.firstChild);
			break;
		case 'beforeEnd':
			this.appendChild(parsedNode);
			break;
		case 'afterEnd':
			if (this.nextSibling) 
				this.parentNode.insertBefore(parsedNode,this.nextSibling);
			else this.parentNode.appendChild(parsedNode);
			break;
		}
	}

	HTMLElement.prototype.insertAdjacentHTML = function(where,htmlStr)
	{
		if(this.parentNode != undefined){
			var r = this.ownerDocument.createRange();
			r.setStartBefore(this);
			var parsedHTML = r.createContextualFragment(htmlStr);
			this.insertAdjacentElement(where,parsedHTML);
		}
	}
}

TreeUtil.getElById = function(idVal) {
  if (document.getElementById != null)
    return document.getElementById(idVal)
  if (document.all != null)
    return document.all[idVal]
  
  alert("Problem getting element by id")
  return null
}

//To customize the tree, overwrite these variables in the configuration file (demoFramesetNode.js, etc.)
TreeUtil.USETEXTLINKS = true;
TreeUtil.STARTALLOPEN = 0;
TreeUtil.USEFRAMES = false;
TreeUtil.WRAPTEXT = 0;
TreeUtil.PERSERVESTATE = 0; //backward compatibility
TreeUtil.PRESERVESTATE = 0;
TreeUtil.ICONPATH = '';
TreeUtil.HIGHLIGHT = 0;
TreeUtil.HIGHLIGHT_COLOR = 'white';
TreeUtil.HIGHLIGHT_BG    = '#316ac5';
TreeUtil.BUILDALL = 0;
TreeUtil.GLOBALTARGET = "R"; // variable only applicable for addChildren uses


//Other variables
TreeUtil.lastClicked = null;
TreeUtil.lastClickedColor;
TreeUtil.lastClickedBgColor;
TreeUtil.browserVersion = 0 
TreeUtil.selectedFolder=0
TreeUtil.lastOpenedFolder=null
TreeUtil.t=5
TreeUtil.doc = document
TreeUtil.supportsDeferral = false

TreeUtil.doc.yPos = 0

// Main function
// ************* 

// This function uses an object (navigator) defined in
// ua.js, imported in the main html page (left frame).
TreeUtil.initializeDocument = function(foldersTree) 
{ 
  TreeUtil.preLoadIcons();
  switch(navigator.family)
  {
    case 'ie4':
      TreeUtil.browserVersion = 1 //Simply means IE > 3.x
      break;
    case 'opera':
      TreeUtil.browserVersion = (navigator.version > 6 ? 1 : 0); //opera7 has a good DOM
      break;
    case 'nn4':
      TreeUtil.browserVersion = 2 //NS4.x 
      break;
    case 'gecko':
      TreeUtil.browserVersion = 3 //NS6.x
      break;
    case 'safari':
      TreeUtil.browserVersion = 1 //Safari Beta 3 seems to behave like IE in spite of being based on Konkeror
      break;
	default:
      TreeUtil.browserVersion = 0 //other, possibly without DHTML  
      break;
  }

  // backward compatibility
  if (TreeUtil.PERSERVESTATE)
    TreeUtil.PRESERVESTATE = 1;

  TreeUtil.supportsDeferral = ((navigator.family=='ie4' && navigator.version >= 5 && navigator.OS != "mac") || TreeUtil.browserVersion == 3);
  TreeUtil.supportsDeferral = TreeUtil.supportsDeferral & (!TreeUtil.BUILDALL)
  if (!TreeUtil.USEFRAMES && TreeUtil.browserVersion == 2)
  	TreeUtil.browserVersion = 0;

  //If TreeUtil.PRESERVESTATE is on, TreeUtil.STARTALLOPEN can only be effective the first time the page 
  //loads during the session. For subsequent (re)loads the TreeUtil.PRESERVESTATE data stored 
  //in cookies takes over the control of the initial expand/collapse

  if(!foldersTree){
  	return;
  }
  //foldersTree (with the site's data) is created in an external .js (demoFramesetNode.js, for example)
  foldersTree.initialize(0, true, "") 
  if (TreeUtil.supportsDeferral && !TreeUtil.STARTALLOPEN) {
      foldersTree.renderOb(null) //delay construction of nodes
  }else {
    TreeUtil.renderAllTree(foldersTree, null);

    if (TreeUtil.browserVersion != 0 && !TreeUtil.STARTALLOPEN)
      TreeUtil.hideWholeTree(foldersTree, false, 0)
  }

  TreeUtil.setInitialLayout(foldersTree);
}
/**
 * 改变一个folder的parent folder
 * @param element
 * 			要改变的element
 * @param newParentElement
 * 			新的parent folder
 */
TreeUtil.changeParentFolder = function(element, newParentElement){
	var folderObj = TreeUtil.getObjByElementId(element.id);
	var newParentObj = TreeUtil.getObjByElementId(newParentElement.id);
	/*
	if(newParentObj.type == "item"){
		newParentObj = newParentObj.parentObj;
	}*/
	if(folderObj == newParentObj || TreeUtil.isAncestor(folderObj, newParentObj)){
		return;
	}
	if(folderObj.parentObj == newParentObj){
		return;
	}
	
	jQuery.post(
		folderObj.data.options.changeParentActionUrl,
		{key:folderObj.data.key, newParentKey: newParentObj.data.key},
		function(dataFromServer){
			dataFromServer = eval("(" + dataFromServer + ")");
			if(dataFromServer[0] == "success"){
				folderObj.navObj.parentNode.removeChild(folderObj.navObj);
				var oldFolderParentObj = folderObj.parentObj;
				oldFolderParentObj.nChildren--;
				Utils.removeElementFromArray(oldFolderParentObj.children, folderObj);
				//如果没子节点了，就变为file
				if(oldFolderParentObj.nChildren <= 0){
					oldFolderParentObj =TreeUtil.changeFolderToFile(oldFolderParentObj);
				}
				
				if(folderObj.isLastNode){
					if(oldFolderParentObj.nChildren > 0){
						var lastChild = oldFolderParentObj.children[oldFolderParentObj.nChildren - 1];
						lastChild.isLastNode = true;
						TreeUtil.reshowFolderAsLastNode(lastChild);
					}
					folderObj.isLastNode = false;
				}else{
					if(newParentObj.nChildren <= 0){
						folderObj.isLastNode = true;
						TreeUtil.reshowFolderAsLastNode(folderObj);
					}
				}
				if(newParentObj.type == "item"){
					newParentObj = TreeUtil.changeFileToFolder(newParentObj);
					folderObj.isLastNode = true;
					TreeUtil.reshowFolderAsLastNode(folderObj);
				}
				folderObj.parentObj = newParentObj;
				folderObj.level = newParentObj.level + 1;
				if(folderObj.isOpen){
					folderObj.setState(false);
				}
				
				newParentObj.children.splice(0, 0, folderObj);
				newParentObj.nChildren++;
				folderObj.isRendered = false;
				
				folderObj.isOpen = false;
				newParentObj.leftSideCoded = TreeUtil.getLeftSideCoded(newParentObj);
				if(newParentObj.isLastNode){
					folderObj.leftSideCoded = newParentObj.leftSideCoded + "0";
				}else{
					folderObj.leftSideCoded = newParentObj.leftSideCoded + "1";
				} 
				if(!newParentObj.isOpen){
					//newParentObj.setState(true);
				}else{
					folderObj.renderOb(newParentObj.navObj);
				}
				TreeUtil.resetAllChildrenUnrendered(folderObj, true);
				
				//通知回调函数
				if(folderObj.data.options.afterChangeParent){
					folderObj.data.options.afterChangeParent(folderObj.data.key, newParentObj.data.key);
				}
			}
			TreeUtil.showAjaxTip(dataFromServer);
		}
	)
	
	
	
}
/**
 * 根据对应的element div id 找到对应的节点对象
 * @param id
 * 			Node div id
 * @return
 * 			成功返回节点对象，失败返回null
 */
TreeUtil.getObjByElementId = function(id){
	var result = null, objId = null;
	if(id.indexOf("drag") != -1){
		objId = id.substring(4);
	}else if(id.indexOf("folder") != -1){
		objId = id.substring(6);
	}else if(id.indexOf("item") != -1){
		objId = id.substring(4);
	}else if(id.indexOf("desc") != -1){
		objId = id.substring(4);
	}
	if(objId != null){
		result = TreeUtil.findObj(objId);
	}
	return result;
}
/**
 * 重置obj的所有子节点为isRendered = false
 * @param obj
 * 			要重置的对象
 * @param isRecursive
 * 			是否递归（即是否对子节点的子节点递归重置）
 */
TreeUtil.resetAllChildrenUnrendered = function(obj, isRecursive){
	var child;
	for(var i=0; i<obj.nChildren; i++){
		child = obj.children[i];
		child.isRendered = false;
		if(isRecursive){
			TreeUtil.resetAllChildrenUnrendered(child, true);
		}
	}

}
/**
 * 把obj作为最后一个node重新显示一遍
 * @param obj
 * 			要显示的folder 对象
 */
TreeUtil.reshowFolderAsLastNode = function(obj){
	obj.leftSideCoded = TreeUtil.getLeftSideCoded(obj);
	var navObj = obj.navObj;
	var imgs = navObj.getElementsByTagName("IMG");
	var img;
	for(var i=0; i<imgs.length; i++){
		img = imgs[i];
		if(img.src.indexOf("ftv2node.gif") != -1){
			img.src = img.src.replace("ftv2node.gif", "ftv2lastnode.gif");
			if(obj.type == "folder"){
				img.parentNode.parentNode.style.background="";
			}else{
				img.parentNode.style.background="";
			}
		}
		if(img.src.indexOf("ftv2pnode.gif") != -1){
			img.src = img.src.replace("ftv2pnode.gif", "ftv2plastnode.gif");
			if(obj.type == "folder"){
				img.parentNode.parentNode.style.background="";
			}else{
				img.parentNode.style.background="";
			}
		}
		if(img.src.indexOf("ftv2mnode.gif") != -1){
			img.src = img.src.replace("ftv2mnode.gif", "ftv2mlastnode.gif");
			if(obj.type == "folder"){
				img.parentNode.parentNode.style.background="";
			}else{
				img.parentNode.style.background="";
			}
		}
	}
	for(var i=0; i<obj.nChildren; i++){
		TreeUtil.reshowOnAncestorChangeToLastNode(obj.children[i], obj.level);
	}
}
TreeUtil.reshowOnAncestorChangeToLastNode = function(obj, ancestorLevel){
	if(obj.navObj){
		var tds = obj.navObj.getElementsByTagName("table")[0].rows[0].cells;
		var td = tds[ancestorLevel - 1];
		if(td){
			td.style.background = "";
			if(td.getElementsByTagName("IMG")[0]){
				td.getElementsByTagName("IMG")[0].src = TreeUtil.ICONPATH + "ftv2blank.gif";
			} 
		}
	}
	obj.leftSideCoded = TreeUtil.getLeftSideCoded(obj);
	if(obj.type == "folder"){
		var child;
		for(var i=0; i<obj.nChildren; i++){
			child = obj.children[i];
			TreeUtil.reshowOnAncestorChangeToLastNode(child, ancestorLevel);
		}
	}
	
}
/**
 * 改变一个item的parent folder
 * @param itemElement
 * 			要改变的item
 * @param newParentElement
 * 			新的parent folder
 */
TreeUtil.changeItemParent = function(itemElement, newParentElement){
	var newParentObj = TreeUtil.getObjByElementId(newParentElement.id);
	/*
 	if(newParentObj.type == "item"){
		newParentObj = newParentObj.parentObj;
	}
	 */
	TreeUtil.changeParentFolder(itemElement, newParentObj.navObj);
}
/**
 * 判断obj是否为myselfObj的祖先
 */
TreeUtil.isAncestor = function(obj, myselfObj){
	var myselfParentObj= myselfObj.parentObj; 
	if(myselfParentObj == null){
		return false;
	}
	if(myselfObj.parentObj == obj){
		return true;
	}else{
		return TreeUtil.isAncestor(obj, myselfParentObj);
	}
}
/**
 * 创建新的folder
 * @param parentObj
 * 			新folder的父节点对象
 * @return 
 * 			返回新创建的folder对象
 */
TreeUtil.createNewFolder = function(parentObj, data){
	var result;
	data.options = parentObj.data.options;
	var obj = TreeUtil.gFld(data.value, "javascript:undefined", parentObj.name, data);
	result = TreeUtil.insFld(parentObj, obj, 2);
	obj.isChildrenDataInitialized = true;
	
	var foldersTree = parentObj.data.options.treeInstance.foldersTree;
	foldersTree.initialize(0, true, "") ;
	if(parentObj.isOpen){
		obj.renderOb(parentObj.navObj);
	}else{
		if(parentObj.nChildren > 0){
			if(parentObj.children[0].isRendered){
				obj.renderOb(parentObj.navObj);
			}
		}
		TreeUtil.clickOnFolder(parentObj.getID());
	}
	return result;
}
/**
 * 创建新的file
 * @param parentObj
 * 			新file的父节点对象
 * @return 
 * 			返回新创建的file对象
 */
TreeUtil.createNewFile = function(parentObj, data){
	var result;
	var url = TreeUtil.getLinkUrl(data, parentObj.link);
	var obj = TreeUtil.gLnk(parentObj.target, data.value, url, parentObj.name, data);
	result = TreeUtil.insDoc(parentObj, obj, 2);
	var foldersTree = parentObj.data.options.treeInstance.foldersTree;
	foldersTree.initialize(0, true, "") ;
	if(parentObj.isOpen){
		obj.renderOb(parentObj.navObj);
	}else{
		if(parentObj.nChildren > 0){
			if(parentObj.children[0].isRendered){
				obj.renderOb(parentObj.navObj);
			}
		}
		TreeUtil.clickOnFolder(parentObj.getID(), false);
	}
	return result;
}
/**
 * 创建新的item
 * @param parentObj
 * 			新folder的父节点对象
 */
TreeUtil.createNewItem = function(parentObj){
	if(parentObj.data.isLeaf){
		parentObj = TreeUtil.changeFileToFolder(parentObj);
	}
	//如果数据没有初始化先初始化
	if(!parentObj.isChildrenDataInitialized){
		TreeUtil.initializeChildrenData(parentObj, TreeUtil.createNewItem.bind(this, parentObj));
		return;
	}
	var data = {};
	data.key = "new" + new Date().getTime();
	data.value = "新建节点";
	data.isLeaf = true;
	data.options = parentObj.data.options;
	var obj = TreeUtil.createNewFile(parentObj, data);
	TreeUtil.startEditObj(
							obj, 
							function(data){
								jQuery.post(
									obj.data.options.createActionUrl,
									{parentKey: parentObj.data.key, isLeaf:true, value: data.value},
									function(dataFromServer){
										dataFromServer = eval("(" + dataFromServer + ")");
										if(dataFromServer[0] == "success"){
											obj.data.key = dataFromServer[4].key;
											var checkbox = $("checkbox" + obj.getID());
											if(checkbox != null){
												checkbox.value = obj.data.key;
											}
											obj.data.options.afterAddFile(data);
										}else{
											TreeUtil.deleteObjFromTreeView(obj);
										}
										TreeUtil.showAjaxTip(dataFromServer);
									}
								)
								
							}
						 );
}
TreeUtil.startEdit = function(obj){
	TreeUtil.startEditObj(
							obj, 
							function(data){
								jQuery.post(
									obj.data.options.updateActionUrl,
									{key:data.key, value: data.value},
									function(dataFromServer){
										dataFromServer = eval("(" + dataFromServer + ")");
										if(dataFromServer[0] == "success"){
											obj.data.key = dataFromServer[4].key;
											obj.data.options.afterEdit(data);
										}
										TreeUtil.showAjaxTip(dataFromServer);
									}
								)
								
							}
						 );
}/**
 * 开始编辑节点obj
 * @param obj
 * 			要编辑的节点对象
 * @param afterEdit
 * 			编辑完成后的回调函数 参数 (data) : {key:, value:}
 */
TreeUtil.startEditObj = function(obj, afterEdit){
	if(obj.toolbar){
		obj.toolbar.stopObserve();
	}
	var descContentId = "descContent" + obj.id;
	var itemTextLinkId = "itemTextLink" + obj.id;
	obj.placeEdit = 
		new Best.PlaceEdit(descContentId, 
				obj.data.key, null,
				{
					userCallBack:
						function(result){
							if(obj.type == "folder"){
								$(itemTextLinkId).onclick = TreeUtil.clickOnNode.bind(this,this.getID());
								$(itemTextLinkId).ondblclick = TreeUtil.dblclickOnNode.bind(this,this.getID());
							}else{
								$(itemTextLinkId).onclick = TreeUtil.clickOnLink.bind(this,this.getID(), this.link, this.target);
								$(itemTextLinkId).ondblclick = TreeUtil.dblclickOnLink.bind(this,this.getID(), this.link, this.target);
							}
							if(this.toolbar)
								this.toolbar.startObserve();
							this.data.value = result.value; 
							this.desc = result.value;
							afterEdit(this.data);
						}.bind(obj)
				}
			);
	obj.placeEdit.startEditing();
	$(itemTextLinkId).onclick = null;
}
/**
 * 获取data的链接地址
 */
TreeUtil.getLinkUrl = function(data, baseUrl){
	var url = baseUrl;
	if(baseUrl == null){
		url = "javascript:undefined";
	}else{
		if(url.indexOf("?") == -1){
			url += "?key=" + data.key;
		}else{
			if(url.indexOf("key=") != -1){
				url.replace("key=[^&]*", "key=" + data.key);
			}else{
				url += "&key=" + node.key;
			}
		}
	}
	return url;
}
/**
 * 删除某个节点
 */
TreeUtil.deleteObj = function(obj){
	jQuery.post(
					obj.data.options.deleteActionUrl,
					{key: obj.data.key},
					function(dataFromServer){
						dataFromServer = eval("(" + dataFromServer + ")");
						if(dataFromServer[0] == "success"){
							TreeUtil.deleteObjFromTreeView(obj);
							//如果没子节点了，就变为file
							if(obj.parentObj.nChildren <= 0){
								if(obj.parentObj.parentObj != null){ //非 root 节点需要转变为file形式
									obj.parentObj =TreeUtil.changeFolderToFile(obj.parentObj);
								}
							}
							if(obj == TreeUtil.getCheckedNode()){
								TreeUtil.lastHighlightNode = null;
							}
							obj.data.options.afterDelete(obj.data);
						}
						TreeUtil.showAjaxTip(dataFromServer);
					}
				)
}
/**
 * 从树的view中删除某个节点
 * @param obj
 * 			要删除的节点的对象
 */
TreeUtil.deleteObjFromTreeView = function(obj){
	var folderObj = obj;
	var id = "drag" + obj.id;
	Droppables.remove($(id));
	if(folderObj.navObj.parentNode != undefined){
		folderObj.navObj.parentNode.removeChild(folderObj.navObj);
	}
	var oldFolderParentObj = folderObj.parentObj;
	oldFolderParentObj.nChildren--;
	Utils.removeElementFromArray(oldFolderParentObj.children, folderObj);
	
	if(folderObj.isLastNode){
		if(oldFolderParentObj.nChildren > 0){
			var lastChild = oldFolderParentObj.children[oldFolderParentObj.nChildren - 1];
			lastChild.isLastNode = true;
			TreeUtil.reshowFolderAsLastNode(lastChild);
		}
		folderObj.isLastNode = false;
	}
	if(folderObj.isOpen){
		folderObj.setState(false);
	}
}
/**
 * 把file变为folder
 * @param obj
 * 			要改变的对象
 */
TreeUtil.changeFileToFolder = function(obj){
	var result;
	TreeUtil.deleteObjFromTreeView(obj);
	obj.data.isLeaf = false;
	result = TreeUtil.createNewFolder(obj.parentObj, obj.data);
	result.isChildrenDataInitialized = true;
	return result;
}
/**
 * 把folder变为file
 * @param obj
 * 			要改变的对象
 */
TreeUtil.changeFolderToFile = function(obj){
	var result;
	TreeUtil.deleteObjFromTreeView(obj);
	obj.data.isLeaf = true;
	result = TreeUtil.createNewFile(obj.parentObj, obj.data);
	return result;
}
/**
 * 显示ajax返回的数据中的提示信息
 */
TreeUtil.showAjaxTip = function(dataFromServer){
	Utils.showAjaxTip(dataFromServer);
}
/**
 * 高亮显示某个节点
 * @param obj
 * 			要高亮显示的节点对象
 */
TreeUtil.highlightNode = function(obj){
	var id= obj.id;
	if(TreeUtil.lastHighlightNode){
		TreeUtil.unhighlightNode(TreeUtil.lastHighlightNode);
	}
	TreeUtil.lastHighlightNode = obj;
	if($('descContent' + id) != null){
		$('descContent' + id).className = 'treeHighlightNode';
	}
}
/**
 * 取消高亮显示某个节点
 * @param obj
 * 			要取消高亮显示的节点对象
 */
TreeUtil.unhighlightNode = function(obj){
	var contentDiv = $('descContent' + obj.id);
	if(contentDiv){
		contentDiv.className = '';
	}
}
/**
 * 获取树中选中的节点对象
 */
TreeUtil.getCheckedNode = function(){
	return TreeUtil.lastHighlightNode;
}
/**
 * 获取某个节点的xpath
 */
TreeUtil.getXpath = function(nodeObj){
	var result = "/" + nodeObj.data.key;
	var parentObj = nodeObj.parentObj;
	while(parentObj != null){
		result = "/" + parentObj.data.key + result;
		parentObj = parentObj.parentObj;
	}
	return result;
}
/**
 * 获取nodeObj在其家庭(父节点的所有子节点的集合)中的排行
 */
TreeUtil.getFamilyIndex = function(nodeObj){
	var result = -1;
	var parentObj = nodeObj.parentObj;
	for(var i=0; i<parentObj.nChildren; i++){
		if(nodeObj == parentObj.children[i]){
			result = i;
			break;
		}
	}
	return result;
}